function Rom(data){
    this.initRom_();
}
/**
 * @constructor
 * @param data {String}
 * @throws {Number}
 *      -1: invalid rom exception!
 *      -2: unsupported mapper!
 */
Rom.prototype.initRom_ = function (data){
    if (!/^NES\x1a/.test(data)) {
        throw -1;
    }
    var offset = 0;
    var buff = Utils.sliceStringAsArray(data, 0, 0x10);
    offset += 0x10;
    this.numPRoms = buff[0x04];
    this.numVRoms = buff[0x05] << 1;
    var flag = buff[0x06];
    this.mirroring = !!(flag & 0x01);
    this.batteryRam = !!(flag & 0x02);
    this.trainer = !!(flag & 0x03);
    this.fourScreen = !!(flag & 0x04) !== 0;

    var mapperCode = (flag >> 4) | (buff[0x07] & 0xF0);
    this.mapper = Mapper.all[mapperCode];
    if (this.mapper == null) {
        throw -2;
    }

    var i;
    this.pRoms = [];
    for (i = 0; i < this.numPRoms; i ++) {
        this.pRoms[i] = Utils.sliceStringAsArray(data, offset, offset + 0x4000);
        offset += 0x4000;
    }
    this.vRoms = [];
    for (i = 0; i < this.numVRoms; i ++) {
        this.vRoms[i] = Utils.sliceStringAsArray(data, offset, offset + 0x1000);
        offset += 0x1000;
    }
};
Rom.prototype.setup = function (bus){
    bus.rom = this;
    this.mapper.setup(bus);
};